package com.example.interview.bean.link;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.example.interview.bean.vo.Bound;
import lombok.Data;

import java.lang.reflect.Type;
import java.util.Stack;

/**
 * @author ：superdyf
 * @date ：Created in 2021/10/28 18:24
 * @description：
 * @modified By：
 */
@Data
public class Node<E>{
    private E e;
    private Node<E> next;
    public static void main(String[] args)  {
        for (int i = 0; i <100 ; i++) {
            Bound t=new Bound();
            Bound s=t;
            System.out.println(t.hashCode());
            System.out.println(s.hashCode());
            t=null;
            System.out.println(t);
            System.out.println(s.hashCode());
            try {
                Thread.sleep(5000);
            } catch (InterruptedException interruptedException) {
                interruptedException.printStackTrace();
            }
        }
    }
    public static void b(){
        int i = 1;
        Node<Integer> root = new Node<>();
        root.setE(i);
        Node<Integer> parent = root;
        while (i <= 10) {
            Node<Integer> next = new Node<>();
            next.setE(++i);
            parent.setNext(next);
            parent = next;
        }
        Node<Integer> child = root;
        Stack<Node<Integer>> stack = new Stack<>();
        while (child.getNext() != null) {
            Node<Integer> n = new Node<>();
            n.setE(child.getE());
            stack.push(n);
            System.out.println(child.getE());
            child = child.getNext();
        }
        Node<Integer> t = null;
        Node<Integer> rev = new Node<>();
        Node<Integer> revparent = rev;
        while (!stack.empty() && (t = stack.pop()) != null) {
            Node<Integer> n = t;
            revparent.setNext(n);
            revparent.setE(n.getE());
            System.out.println(n.getE());
            revparent = t;
        }
        recursion(rev);
        Node<Integer> retestroot = new Node<>();
        retestroot.setE(1);
        for (int j = 2; j <= 10; j++) {
            Node<Integer> n = new Node<>();
            n.setE(j);
            recursionAdd(retestroot, n);
        }
        System.out.println("================retestroot");
        recursion(retestroot);
        Node<Integer> revnode = revByrec(retestroot);
        iter(revnode);
        System.out.println(JSON.toJSONString(copy(revnode),SerializerFeature.DisableCircularReferenceDetect));
    }
    private static <E> void iter(Node<E> root) {
        Node<E> child = root;
        System.out.println(child.hashCode()+":\t"+root.hashCode());
        while (child!=null) {
            System.out.println(child.getE());
            child = child.getNext();
        }
    }

    private static <E> void recursion(Node<E> root) {
        if (null != root) {
            System.out.println("pre:" + root.getE());
            recursion(root.getNext());
            System.out.println("post:" + root.getE());
        }
    }

    /**
     * @return void
     * @Author superdyf
     * @Description //TODO link
     * @Date 11:26 2021/10/29
     * @Param [root, next]
     **/
    private static <E> void recursionAdd(Node<E> root, Node<E> next) {
        if (root == null) {
            return;
        }
        if (null == root.getNext()) {
            root.setNext(next);
        } else {
            recursionAdd(root.getNext(), next);
        }
    }
    public static <E> Node<E> rev(Node<E> node) throws CloneNotSupportedException {
        Type type = new TypeReference<Node<E>>() {}.getType();
        Node<E> rev=null;
        Node<E> parent= JSON.parseObject(JSON.toJSONString(node, SerializerFeature.DisableCircularReferenceDetect),type, Feature.DisableCircularReferenceDetect);
        Node<E> next=null;
        while(parent!=null){
            Node<E> n=parent.getNext();
            if(n==null){
                rev=parent;
            }
            parent.setNext(next);
            next=parent;
            parent=n;
        }
        return rev;
    }
    public static <E> Node<E> revByrec(Node<E> e){
            if(null==e||e.getNext()==null)return e;
            Node<E> n=revByrec(e.getNext());
            e.getNext().setNext(e);
            e.setNext(null);
            return n;
    }
    public static <E> Node<E> copy(Node<E> source) {
        if(source==null||source.getNext()==null){
            return source;
        }
        Node<E> child=source;
        Node<E> parent=new Node<>();
        parent.setE(child.getE());
        Node<E> newNode=parent;
        while(child!=null){
            child=child.getNext();
            if(newNode!=null&&child!=null&&newNode.getNext()==null){
                Node<E> e=new Node<>();
                e.setE(child.getE());
                newNode.setNext(e);
                newNode=newNode.getNext();
            }
        }
        return parent;
    }
}
